import json
import datetime
from PIL import Image
from django.utils import timezone
from django.db import models
from django.conf import settings

from utils.exception import CustomError
from utils.format import strftime, strfdate
from utils.uploadfile import SaveTempFile


# get_user_model()实际获取的是settings.AUTH_USER_MODEL指定的User model
# User = get_user_model()


# Create your models here.


class VCode(models.Model):
    """验证码"""
    SIGN = 1
    FORGET_PASSWORD = 2
    TYPE_CHOICES = (
        (SIGN, '注册'),
        (FORGET_PASSWORD, '忘记密码')
    )

    SUCCESSED = 1
    FAILED = 0
    STATUS_CHOICES = (
        (SUCCESSED, '发送成功'),
        (FAILED, '发生失败')
    )

    vcode = models.CharField(max_length=4, verbose_name='验证码')
    mobile = models.CharField(verbose_name='手机号', max_length=11)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    type = models.PositiveSmallIntegerField(verbose_name='用途', choices=TYPE_CHOICES, editable=False, default=SIGN)
    status = models.PositiveSmallIntegerField(verbose_name='状态', choices=STATUS_CHOICES, editable=False,
                                              default=SUCCESSED)
    error = models.CharField(verbose_name='错误原因', max_length=200, null=True)
    is_used = models.BooleanField(verbose_name='是否已经验证过', default=False)

    @staticmethod
    def verify(mobile, code, type):
        if mobile is None and code is None:
            raise CustomError("参数无效！")

        if type not in [VCode.SIGN, VCode.FORGET_PASSWORD]:
            raise CustomError("参数无效！")

        vc = VCode.objects.filter(mobile=mobile, type=type, status=VCode.SUCCESSED, is_used=False).order_by(
            '-id').first()

        if vc:
            if vc.vcode == code:
                if (timezone.now() - vc.create_time).seconds < 600:
                    return vc
                raise CustomError("验证码已过期！")
        raise CustomError("验证码错误")

    class Meta:
        db_table = 'system_code'
        verbose_name = '短息验证码'
        ordering = ['-create_time']
        default_permissions = ()


class LogManager(models.Manager):
    def addLog(self, user, type, description, data=None):
        def default(o):
            if isinstance(o, datetime.datetime):
                return strftime(o)
            elif isinstance(o, datetime.date):
                return strfdate(o)

        log = self.model(user=user, type=type, description=description)
        if data:
            # default  迭代
            log.data = json.dumps(data, default=default)
        log.save()
        return log


class Log(models.Model):
    INSERT = 1
    DELETE = 2
    UPDATE = 3

    TYPE_CHOICES = (
        (INSERT, '插入'),
        (DELETE, '删除'),
        (UPDATE, '更新')
    )

    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='操作人', on_delete=models.PROTECT)
    type = models.PositiveSmallIntegerField(verbose_name='操作类型', choices=TYPE_CHOICES)
    description = models.CharField(verbose_name='操作描述', max_length=1000)
    data = models.TextField(verbose_name='操作数据', null=True)
    create_time = models.DateTimeField(verbose_name='操作时间', auto_now_add=True, editable=False)

    objects = LogManager()

    class Meta:
        db_table = 'system_log'
        verbose_name = '后台系统日志'
        ordering = ['-create_time']
        index_together = ('create_time',)


class Config(models.Model):
    KEY_SENSITIVE_WORDS = 'sensitive_words'  # 敏感词
    KEY_SENSITIVE_WORDS_NICKNAME = 'sensitive_words_nickname'  # 敏感词

    key = models.CharField(verbose_name='属性', max_length=100)
    value = models.TextField(verbose_name='值', max_length=500, null=True, blank=True)

    class Meta:
        db_table = 'system_config'
        verbose_name = '系统设置'
        default_permissions = ()

    @staticmethod
    def get_sensitive_words():
        try:
            row = Config.objects.filter(key=Config.KEY_SENSITIVE_WORDS).first()
            if row:
                return row.value.split('|')
        except:
            pass
        return []

    @staticmethod
    def get_sensitive_words_nickname():
        try:
            row = Config.objects.get(key=Config.KEY_SENSITIVE_WORDS_NICKNAME)
            if row:
                return row.value.split('|')
        except:
            pass
        return []


class Category(models.Model):
    BOTH = 0
    ARTICLE = 1
    NEWS = 2

    TYPE_CHOICES = (
        (BOTH, '全部'),
        (ARTICLE, '文章'),
        (NEWS, '新闻')
    )

    CATEGORY = 1
    TAG = 2
    CLASSIFY_CHOICES = (
        (CATEGORY, '分类'),
        (TAG, '标签')
    )

    name = models.CharField(verbose_name='名称', max_length=50)
    classify = models.PositiveSmallIntegerField(verbose_name='分类', choices=CLASSIFY_CHOICES)
    type = models.PositiveSmallIntegerField(verbose_name='类型', choices=TYPE_CHOICES, default=BOTH)
    sort = models.PositiveSmallIntegerField(verbose_name='排序', help_text='越小越靠前', default=0)

    def __unicode__(self):
        return self.name

    class Meta:
        db_table = 'system_category'
        verbose_name = '标签分类'
        ordering = ['-classify', 'sort']


class UploadManager(models.Manager):
    def upload(self, user, file):
        # 文件名
        file_name = 'user-%s-%s.%s' % (
            str(user.id), timezone.now().strftime('%Y%m%d%H%M%S%f'), file.name.split('.')[-1])
        width = None
        height = None
        # 1.保存到本地
        file_name = file_name.lower()
        file_path = SaveTempFile(file, file_name)

        # 2.剪切图片
        # try:
        #     img = Image.open(file_path)
        #     x, y = img.size
        #     if x > 1440:
        #         img = img.resie((1440, int((y / x) * 1440)), Image.ANTIALIAS)
        #         img.save(file_path)
        #     width, height = img.size
        # except:
        #     pass

        # # 3.上传到七牛云
        # qiniu_path = '七牛云路径'
        # from qiniu import Auth, put_file
        # q = Auth('LMzmBFFeX5Fnyi9y70s4bvPilscOwQyWILGvP3Y', 'JBz5LfYc6PgWezUbFdDX03ngqXK89JV6_O8d_Rkx')
        # # 要上传的空间
        # bucket_name = 'Bucket_Name'
        # # 上传后保存的文件名
        # key = file_name
        # # 生成上传 Token，可以指定过期时间等
        # token = q.upload_token(bucket_name, key, 3600)
        # # 要上传文件的本地路径
        # localfile = './sync/bbb.jpg'
        #
        #
        # ret, info = put_file(token, key, localfile)
        # print(info)
        # 4.保存
        instance = Upload.objects.create(filename=file_name, filepath=file_path, user=user, width=width, height=height)
        print(instance)
        return instance


class Upload(models.Model):
    filename = models.CharField(verbose_name='图片名称', max_length=100)
    filepath = models.CharField(verbose_name='路径', max_length=200)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True, editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='上传者', on_delete=models.PROTECT)
    width = models.IntegerField(verbose_name='图片宽度', null=True)
    height = models.IntegerField(verbose_name='图片长度', null=True)

    objects = UploadManager()

    class Meta:
        db_table = 'upload'
        verbose_name = '图片'
        default_permissions = ()
